/*
 * @Description:
 * @Author: dh
 * @Date: 2021-09-24 15:11:50
 * @LastEditors: dh
 * @LastEditTime: 2024-05-14 16:21:06
 */

// TODO 0 ReadonlyArray<T>属性，确保数组创建后不能再被修改。
let ro1: Array<number> = [1, 2]
let ro2: ReadonlyArray<number> = [1, 2]

interface UserType {
	name?: string
	age?: number
}

// TODO 1 readonly 只读
interface Person2 {
	readonly name: string
	age?: number
}
// 全部转为只读 Readonly
type ReaType = Readonly<UserType>
const uer3: ReaType = { name: 'deng', age: 20 }

// TODO 2 Required 全部转为必须
type ReType = Required<UserType>
const uer1: ReType = { name: 'deng', age: 20 }

// TODO 3 Partial  全部转为可选
type ParType = Partial<ReType>
const uer2: ParType = { name: 'deng' }

// TODO 4 Extract 选择两种不同类型中的共有属性来构造新的类型。返回字面量类型
interface FirstType {
	id: number
	firstName: string
	lastName: string
	name: string
}
interface SecondType {
	id: number
	address: string
	city: string
	name: string
}
type ExtractType1 = Extract<keyof FirstType, keyof SecondType>
// Output: "id"|"name"

// TODO 5 Exclude 通过排除两个不同类型中已经存在的共有属性,返回前者剩余属性来构造新的类型。与 Extract 相反
type ExcludeType2 = Exclude<keyof FirstType, keyof SecondType>
// Output; "firstName" | "lastName"

// TODO 5 Record 记录/记载, 作用是将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型
type petsGroup = 'dog' | 'cat' | 'fish'
type numOrStr = number | string
type IPets = Record<petsGroup, numOrStr>

const ani: IPets = { dog: 1, cat: 2, fish: '3' }

// TODO ReturnType  从一个函数类型的返回类型构建一个类型
import axios from 'axios'
type Response = ReturnType<typeof axios>
const res: Response = axios('url')

// 定义key为number，值为字符串
type IPets2 = Record<number, string>
// 结果
// type IPets = {
//     [key:string]: numOrStr;
// }
const ani2: IPets2 = { 0: '1', 1: '2', 2: '3' }

// 用来得到一个函数的返回值类型
type Func = (value: string) => string
type Func2 = ReturnType<Func>

// TODO 6 Pick 挑选属性组成新的类型
interface PickType {
	id: number
	name: string
	age: number
}
type PickB = Pick<PickType, 'id' | 'name'>
// type PickB = {
//     id: number;
//     name: string;
// }

// TODO 7 Omit 排除这些属性组成新的类型 , 与Pick相反
type OmitB = Omit<PickType, 'id' | 'name'>
// type PickB = {
//     age: number;
// }

// TODO 8 NonNullable 去除类型中的 null 和 undefined
type P1 = NonNullable<string | number | undefined> // string | number
type P2 = NonNullable<string[] | null | undefined> // string[]

// TODO 10 Parameters 用于获得函数的参数类型所组成的元组类型。
type P3 = Parameters<(a: number, b: string) => void> // [number, string]

// TODO 11 InstanceType 返回构造函数类型T的实例类型,接口组件，可获取组件暴露的属性和方法
class C {
	x = 0
	y = 0
}
type D1 = Omit<InstanceType<typeof C>, ''> // C
